﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WucCloud.Entity;

namespace WucCloud.Database
{
    /// <summary>
    /// 泛型仓储 实现
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public class BaseRepository<TEntity> :IBaseRepository<TEntity> where TEntity : class, new()
    {
        /// <summary>
        /// 用于其他表操作（事务操作）
        /// </summary>
        private readonly IUnitOfWork _unitOfWork;

        /// <summary>
        /// 用于当前表操作
        /// </summary>
        private SqlSugarClient _dbBase;

        /// <summary>
        /// 数据库操作对象
        /// </summary>
        private ISqlSugarClient _db
        {
            get
            {
                #region CodeFirst 如果不存在数据库 就创建
                ////创建数据库
                //_dbBase.DbMaintenance.CreateDatabase();
                ////创建表
                //_dbBase.CodeFirst.InitTables(
                //        typeof(UserInfoEntity),
                //        typeof(RoleInfoEntity),
                //        typeof(UserRoleEntity),
                //        typeof(MenuInfoEntity),
                //        typeof(RoleMenuEntity),
                //        typeof(OrganizeInfoEntity)
                //    );
                #endregion

                //获取configid  即数据库的唯一标识
                var configId = typeof(TEntity).GetCustomAttribute<TenantAttribute>().configId;
                if (configId != null)
                {
                    //实现动态切换数据库
                    _dbBase.ChangeDatabase(configId);                    
                }

                return _dbBase;
            }

        }   

        /// <summary>
        /// SqlSugarClient实体
        /// </summary>
        public ISqlSugarClient Db
        {
            get { return _db; }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="unitOfWork"></param>
        public BaseRepository(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
            _dbBase = unitOfWork.GetDbClient();
        }

        #region Basic 基础方法
        /// <summary>
        /// 实体集合
        /// </summary>
        /// <returns></returns>
        public ISugarQueryable<TEntity> SugarQueryable()
        {
            return _db.Queryable<TEntity>();
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        public IInsertable<TEntity> Insertable(TEntity entity)
        {
            return _db.Insertable(entity);
        }

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="entities">实体对象集合</param>
        /// <returns></returns>
        public IInsertable<TEntity> Insertable(List<TEntity> entities)
        {
            return _db.Insertable(entities);
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        public IUpdateable<TEntity> Updateable(TEntity entity)
        {
            return _db.Updateable(entity);
        }

        /// <summary>
        /// 批量编辑
        /// </summary>
        /// <param name="entities">实体对象集合</param>
        /// <returns></returns>
        public IUpdateable<TEntity> Updateable(List<TEntity> entities)
        {
            return _db.Updateable(entities);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <returns></returns>
        public IDeleteable<TEntity> Deleteable()
        {
            return _db.Deleteable<TEntity>();
        }
        #endregion

        #region Insert 新增方法
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns>是否新增成功</returns>
        public async Task<bool> InsertAsync(TEntity entity)
        {
            return await _db.Insertable(entity).ExecuteCommandIdentityIntoEntityAsync();
        }

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="entities">实体对象集合</param>
        /// <returns>是否新增成功</returns>
        public async Task<bool> InsertAsync(List<TEntity> entities)
        {
            return await _db.Insertable(entities).ExecuteCommandIdentityIntoEntityAsync();
        }
        #endregion

        #region Update 编辑方法
        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns>是否编辑成功</returns>
        public async Task<bool> UpdateAsync(TEntity entity)
        {
            return await _db.Updateable(entity).ExecuteCommandHasChangeAsync();
        }

        /// <summary>
        /// 批量编辑
        /// </summary>
        /// <param name="entities">实体对象集合</param>
        /// <returns>是否编辑成功</returns>
        public async Task<bool> UpdateAsync(List<TEntity> entities)
        {
            return await _db.Updateable(entities).ExecuteCommandHasChangeAsync();
        }
        #endregion

        #region Delete 删除方法

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="keyId">主键Id</param>
        /// <returns>是否删除成功</returns>
        public async Task<bool> DeleteAsync(string keyId)
        {
            return await _db.Deleteable<TEntity>(keyId).ExecuteCommandHasChangeAsync();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns>是否删除成功</returns>
        public async Task<bool> DeleteAsync(TEntity entity)
        {
            return await _db.Deleteable(entity).ExecuteCommandHasChangeAsync();
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="entities">实体对象集合</param>
        /// <returns>是否删除成功</returns>
        public async Task<bool> DeleteAsync(TEntity[] entities)
        {
            return await _db.Deleteable<TEntity>(entities).ExecuteCommandHasChangeAsync();
        }
        #endregion

        #region Query 查询方法

        /// <summary>
        /// 校验数据是否存在
        /// </summary>
        /// <param name="expression">Lambda表达式（查询条件）</param>
        /// <returns></returns>
        public async Task<bool> AnyAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await SugarQueryable().AnyAsync(expression);
        }

        /// <summary>
        /// 检查信息总条数
        /// </summary>
        /// <param name="expression">Lambda表达式（查询条件）</param>
        /// <returns></returns>
        public async Task<int> CountAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await SugarQueryable().CountAsync(expression);
        }

        /// <summary>
        /// 通过Id查询
        /// </summary>
        /// <param name="keyId">主键Id</param>
        /// <returns></returns>
        public async Task<TEntity> FindByIdAsync(string keyId)
        {
            return await SugarQueryable().InSingleAsync(keyId);
        }

        /// <summary>
        /// 自定义条件查询（单条）
        /// </summary>
        /// <param name="expression">Lambda表达式（查询条件）</param>
        /// <returns></returns>
        public async Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await SugarQueryable().SingleAsync(expression);
        }

        /// <summary>
        /// 查询所有
        /// </summary>
        /// <returns></returns>
        public async Task<List<TEntity>> QueryableAsync()
        {
            return await SugarQueryable().ToListAsync();
        }

        /// <summary>
        /// 自定义条件查询（多条）
        /// </summary>
        /// <param name="expression">Lambda表达式（查询条件）</param>
        /// <returns></returns>
        public async Task<List<TEntity>> QueryableAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await SugarQueryable()
                .Where(expression)
                .ToListAsync();
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        public async Task<List<TEntity>> QueryableAsync(PageModel page)
        {
            return await SugarQueryable()
                .ToPageListAsync(page.PageIndex, page.PageSize);
        }

        /// <summary>
        /// 自定义条件分页查询
        /// </summary>
        /// <param name="expression">Lambda表达式（查询条件）</param>
        /// <param name="page">分页组件类</param>
        /// <returns></returns>
        public async Task<List<TEntity>> QueryableAsync(Expression<Func<TEntity, bool>> expression, PageModel page)
        {
            return await SugarQueryable()
                .Where(expression)
                .ToPageListAsync(page.PageIndex, page.PageSize);
        }
        #endregion
    }
}
